package cn.edu.tju.elm.service;

import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.repository.UserRepository;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.elm.exception.MethodArgumentNotValidException;
import cn.edu.tju.elm.model.DTO.CartDTO;
import cn.edu.tju.elm.model.entity.Business;
import cn.edu.tju.elm.model.entity.Cart;
import cn.edu.tju.elm.model.entity.Food;
import cn.edu.tju.elm.repository.BusinessRepository;
import cn.edu.tju.elm.repository.CartRepository;
import cn.edu.tju.elm.repository.FoodRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@AllArgsConstructor
public class CartService {
    private final CartRepository cartRepository;
    private final FoodRepository foodRepository;
    private final BusinessRepository businessRepository;
    private final UserRepository userRepository;
    private final UserService userService;

    /**
     * 新增商品到购物车
     * @param cart food_id 和 quantity 是必须的。无须business_id，通过food查找
     * @return Cart
     */
    public Cart addCart(Cart cart) {
        Food existingFood = foodRepository.findById(cart.getFood().getId())
                .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：商品不存在"));
        if(cart.getQuantity()<=0){
            throw new MethodArgumentNotValidException("请求参数非法：商品数量不能低于1");
        }

        Business existingBusiness = existingFood.getBusiness();

        User nowUser = userService.getUserWithAuthorities();

        LocalDateTime now = LocalDateTime.now();

        Cart newCart = Cart.builder()
                .quantity(1)
                .customer(nowUser)
                .food(existingFood)
                .business(existingBusiness)

                .createTime(now)
                .updateTime(now)
                .creator(nowUser.getId())
                .updater(nowUser.getId())
                .deleted(false)

                .build();

        return cartRepository.save(newCart);
    }

    public Cart patchCartQuantity(CartDTO cartDTO) {
        User nowUser = userService.getUserWithAuthorities();
        Business exBusiness = businessRepository.findById(cartDTO.getBusinessId())
                .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：店铺不存在"));
        Food exFood = foodRepository.findById(cartDTO.getFoodId())
                .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：商品不存在"));
        if(!exFood.getBusiness().equals(exBusiness)){
            throw new MethodArgumentNotValidException("请求参数非法：商品不属于该店铺");
        }
        Cart exCart = cartRepository.findAllByCustomerAndBusinessAndFood(nowUser,exBusiness,exFood);

        LocalDateTime now = LocalDateTime.now();

        if(exCart==null && cartDTO.getQuantity()>0){
            exCart = Cart.builder()
                    .quantity(cartDTO.getQuantity())
                    .food(exFood)
                    .customer(nowUser)
                    .business(exBusiness)

                    .createTime(now)
                    .updateTime(now)
                    .creator(nowUser.getId())
                    .updater(nowUser.getId())
                    .deleted(false)

                    .build();

            return  cartRepository.save(exCart);
        }

        if(exCart!=null && cartDTO.getQuantity()<=0){
            cartRepository.delete(exCart);
            return null;
        }

        if(exCart==null && cartDTO.getQuantity()<=0){
            return null;
        }

        if(exCart!=null && cartDTO.getQuantity()>0){
            exCart.setQuantity(cartDTO.getQuantity());
            return cartRepository.save(exCart);
        }
        return exCart;
    }

    public List<Cart> findCartByBusiness(Long businessId) {
        User nowUser = userService.getUserWithAuthorities();
        Business nowBusiness = businessRepository.findById(businessId)
                .orElseThrow(() -> new MethodArgumentNotValidException("请求参数非法：店铺不存在"));
        return cartRepository.findAllByCustomerAndBusiness(nowUser,nowBusiness);
    }
}
